package cn.tedu.mall.service;

import cn.tedu.mall.anno.CacheFind;
import cn.tedu.mall.mapper.ItemCatMapper;
import cn.tedu.mall.pojo.ItemCat;
import cn.tedu.mall.vo.EasyUITable;
import cn.tedu.mall.vo.EasyUITree;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.List;

@Service
public class ItemCatServiceImpl implements ItemCatService{
    @Autowired
    private ItemCatMapper itemCatMapper;

    @Override
    public String findItemCatName(Long itemCatId) {
        //业务：基于商品分类id，去获取商品分类的名称
        ItemCat itemCat = itemCatMapper.selectById(itemCatId);
        //获取商品分类的名称
        return itemCat.getName();
    }

    /**
     * 业务实现分析：
     * 基于parentId所查询到的节点对象是ItemCat类型的对象---pojo
     *在业务中，基于parentId所获取到节点对象是EasyUITree类型---vo
     * 所以需要我们将ItemCat类型的对象转换成EasyUITree类型的对象
     * @param parentId 请求参数
     * @return List<EasyUITree>
     */

    @Override
    @CacheFind
    public List<EasyUITree> findTreeByParentId(Long parentId) {
        //1.通过该方法getItemCatList()基于parentId获取子级节点
        List<ItemCat> itemCatList=getItemCatList(parentId);
        //2.声明一个List<EasyUITree>集合
        List<EasyUITree> treeList=new ArrayList<>(itemCatList.size());
        //3.将pojo（ItemCat）转换成vo（EasyUITree）
        for (ItemCat itemCat:itemCatList) {
            //如果是父级节点就关闭，如果是子级节点就打开
            String state=itemCat.getIsParent()?"closed":"open";
            //创建EasyUITree对象
            EasyUITree tree=new EasyUITree();
            tree.setId(itemCat.getId());
                    tree.setText(itemCat.getName());
                            tree.setState(state);
            treeList.add(tree);
        }
        return treeList;
    }


    private List<ItemCat> getItemCatList(Long parentId) {
        QueryWrapper<ItemCat> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("parent_id",parentId);
        return itemCatMapper.selectList(queryWrapper);
    }

    /**
     * 缓存数据的要求：
     * 1.redis保存的数据结构 K:V结构 ，Key唯一：包名.类名.方法名：：第一个参数名
     * 2.V:保存为字符串String，java对象~json串~字符串
       缓存业务如何实现：
       1.先去redis服务器的数据，基于key去获取数据
       2.没有数据，第一次查询，先从数据库中进行查询，查到时候先加载redis服务器，然后再返回数据
       3.有数据，不是第一次查询，直接讲数据返回
     */
    private ObjectMapper objectMapper=new ObjectMapper();
    @Autowired
    private Jedis jedis;
    @Override
    public List<EasyUITree> findItemCatListByCache(Long parentId) throws JsonProcessingException {
        long start = System.currentTimeMillis();
        String key="cn.tedu.mall.service.ItemCatServiceImpl.findItemCatListByCache::"+parentId;
        //基于key到redis服务器中获取数据
        String json = jedis.get(key);
        List<EasyUITree> list=new ArrayList<>();
        //判断json是否为空，如果为空：说明第一次查询，缓存中没数据
        if (StringUtils.isEmpty(json)){
            //第一次查询，应该查询数据库
            list=findTreeByParentId(parentId);
            long end1=System.currentTimeMillis();
            //将java对象转换成json
            String jsonData = objectMapper.writeValueAsString(list);
            //将查询的数据存储到redis中
            jedis.set(key,jsonData);
            System.out.println("第一次查询数据库，用时:"+(end1-start));
        }else {
            //说明redis中有数据，不是第一次查询
            //将json转换成java对象
           list= objectMapper.readValue(json,List.class);
           long end2=System.currentTimeMillis();
            System.out.println("查询缓存的时长为:"+(end2-start));
        }
        return list;
    }

}
